<template>
  <page-header-wrapper>
    <a-card>
      <!--搜索区域-->
      <div class='table-page-search-wrapper' v-if='tableIndex === 1'>
        <a-form layout='inline'>
          <a-row :gutter='48'>
            <a-col :md='8' :sm='24'>
              <a-form-item label='操作名称'>
                <a-input v-model='queryParam.title' placeholder='请输入操作名称或关键字' />
              </a-form-item>
            </a-col>
            <a-col :md='8' :sm='24'>
              <a-form-item label='操作类型'>
                <a-select v-model='queryParam.businessType' placeholder='请选择操作类型' :allowClear='true'>
                  <a-select-option v-for='oper in operTypeList' :key='oper.businessType' :value='oper.businessType'>
                    {{ oper.businessType + '. ' + oper.description }}
                  </a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
            <a-col :md='8' :sm='24'>
              <a-form-item label='操作人员姓名'>
                <a-input v-model='queryParam.operName' placeholder='请输入操作名称或关键字' />
              </a-form-item>
            </a-col>
            <!--展开区域 => 高级搜索功能-->
            <template v-if='advanced'>
              <a-col :md='8' :sm='24'>
                <a-form-item label='操作人IP'>
                  <a-input v-model='queryParam.operIp' placeholder='请输入操作地址或关键字' />
                </a-form-item>
              </a-col>
              <a-col :md='8' :sm='24'>
                <a-form-item label='操作状态'>
                  <a-select v-model='queryParam.status' placeholder='请选择操作状态' :allowClear='true'>
                    <a-select-option value='0'>成功</a-select-option>
                    <a-select-option value='1'>异常</a-select-option>
                  </a-select>
                </a-form-item>
              </a-col>
              <a-col :md='8' :sm='24'>
                <a-form-item label='操作日期'>
                  <a-range-picker @change='addDataQueryParam' style='width: 100%' />
                </a-form-item>
              </a-col>
            </template>
            <a-col :md='!advanced && 8 || 24' :sm='24'>
              <span class='table-page-search-submitButtons'
                    :style="advanced && { float: 'right', overflow: 'hidden' } || {} ">
                <a-button type='primary' @click='getLogList'>查询</a-button>
                <a-button style='margin-left: 8px' @click='() => {this.queryParam = {};getLogList()}'>重置</a-button>
                <a-button style='margin-left: 8px' @click='() => {exportLogList()}'>导出操作日志</a-button>
                <a @click='toggleAdvanced' style='margin-left: 8px'>
                  {{ advanced ? '收起' : '高级搜索' }}
                  <a-icon :type="advanced ? 'up' : 'down'" />
                </a>
              </span>
            </a-col>
          </a-row>
        </a-form>
      </div>
      
      <div class='table-page-search-wrapper' v-if='tableIndex === 2'>
        <a-form layout='inline'>
          <a-row :gutter='48'>
            <a-col :md='8' :sm='24'>
              <a-form-item label='用户ID'>
                <a-input v-model='queryParam2.userId' placeholder='请输入用户ID' />
              </a-form-item>
            </a-col>
            <a-col :md='8' :sm='24'>
              <a-form-item label='操作状态'>
                <a-select v-model='queryParam2.status' placeholder='请输入操作状态' :allowClear='true'>
                  <a-select-option value='0'>成功</a-select-option>
                  <a-select-option value='1'>异常</a-select-option>
                </a-select>
              </a-form-item>
            </a-col>
            <a-col :md='8' :sm='24'>
              <a-form-item label='用户账号'>
                <a-input v-model='queryParam2.userName' placeholder='用户账号' />
              </a-form-item>
            </a-col>
            <a-col :md='!advanced && 8 || 24' :sm='24'>
              <span class='table-page-search-submitButtons'
                    :style="advanced && { float: 'right', overflow: 'hidden' } || {} ">
                <a-button type='primary' @click='getLogList'>查询</a-button>
                <a-button style='margin-left: 8px'
                          @click='() => {this.queryParam2 = {};getAccessLogList()}'>重置</a-button>
                <a-button style='margin-left: 8px' @click='() => {exportAccessLogList()}'>导出访问日志</a-button>
              </span>
            </a-col>
          </a-row>
        </a-form>
      </div>
      
      <a-tooltip title='刷新'>
        <a-icon type='reload' style='font-size: 18px;cursor: pointer;margin-bottom: 20px;' @click='reloadData' />
      </a-tooltip>
      
      <!--日志类别切换-->
      <a-tabs type='card' @change='changeTableIndex'>
        <a-tab-pane tab='操作日志' :key='1'>
          <a-table
            :columns='columns'
            rowKey='operId'
            :pagination='pagination'
            bordered
            :loading='loading'
            @change='handleTableChange'
            :data-source='tableData'>
            
            <div slot='operType' slot-scope='operType'>
              <a-tag color='geekblue'>{{ operType }}</a-tag>
            </div>
            
            <div slot='status' slot-scope='status'>
              <a-tag :color='status === 0 ? "green" : "volcano"'>{{ status === 0 ? '成功' : '异常' }}</a-tag>
            </div>
            
            <template slot='action' slot-scope='text, record, index'>
              <a-button
                type='primary'
                @click='showLogInfoModal(record)'
                style='border-radius: 5px'>查看
              </a-button>
            </template>
          
          </a-table>
        </a-tab-pane>
        
        <a-tab-pane tab='访问日志' :key='2'>
          <a-table
            :columns='accessLogColumns'
            rowKey='infoId'
            :pagination='pagination'
            bordered
            :loading='loading'
            @change='handleTableChange'
            :data-source='accessLogList'>
            <div slot='status' slot-scope='status'>
              <a-tag :color='status === "0" ? "green" : "volcano"'>{{ status === '0' ? '成功' : '异常' }}</a-tag>
            </div>
            
            <div slot='msg' slot-scope='msg'>
              {{ msg === '' ? '无' : msg }}
            </div>
          
          </a-table>
        </a-tab-pane>
      </a-tabs>
    
    </a-card>
    
    <a-modal
      width='20'
      title='日志信息'
      :centered='true'
      :visible='visible'
      @ok='handleOk'
      okText='确认'
      cancelText='取消'
      @cancel='handleOk'
    >
      <a-descriptions bordered>
        <a-descriptions-item label='操作名称'>
          {{ modalForm.title }}
        </a-descriptions-item>
        <a-descriptions-item label='请求地址'>
          {{ modalForm.operUrl }}
        </a-descriptions-item>
        <a-descriptions-item label='请求方式'>
          <a-tag color='skyblue'>
            {{ modalForm.requestMethod }}
          </a-tag>
        </a-descriptions-item>
        <a-descriptions-item label='操作方法'>
          {{ modalForm.method }}
        </a-descriptions-item>
        <a-descriptions-item label='请求参数'>
          <json-viewer :value='toJson(modalForm.operParam)'></json-viewer>
        </a-descriptions-item>
        <a-descriptions-item label='返回参数'>
          <div style='width: 300px;'>
            <json-viewer :value='toJson(modalForm.jsonResult)'></json-viewer>
          </div>
        </a-descriptions-item>
        <a-descriptions-item label='操作状态'>
          <a-tag :color='modalForm.status === 0 ? "green" : "volcano"'>{{ modalForm.status === 0 ? '成功' : '异常' }}
          </a-tag>
        </a-descriptions-item>
        <a-descriptions-item label='异常信息'>
          {{ modalForm.errorMsg || '无' }}
        </a-descriptions-item>
        <a-descriptions-item label='操作时间'>
          {{ modalForm.operTime }}
        </a-descriptions-item>
      </a-descriptions>
    </a-modal>
  
  </page-header-wrapper>
</template>

<script>
import JsonViewer from 'vue-json-viewer'
import FileSaver from 'file-saver'
import { exportAccessLogList, exportLogList, getAccessLogList, getLogList, getOperTypeList } from '@/api/log'
import { formattedDate } from '@/utils/util'

const columns = [
  {
    title: '日志编号',
    dataIndex: 'operId',
    scopedSlots: { customRender: 'operId' }
  },
  {
    title: '执行操作',
    dataIndex: 'title',
    scopedSlots: { customRender: 'operType' }
  },
  {
    title: '操作人员',
    dataIndex: 'operName',
    scopedSlots: { customRender: 'operName' }
  },
  {
    title: '操作地址',
    dataIndex: 'operIp',
    scopedSlots: { customRender: 'operIp' }
  },
  {
    title: '操作状态',
    dataIndex: 'status',
    scopedSlots: { customRender: 'status' }
  },
  {
    title: '操作时间',
    dataIndex: 'operTime',
    scopedSlots: { customRender: 'operTime' }
  },
  {
    title: '耗费时间',
    dataIndex: 'costTime',
    customRender: (text) => text + ' 毫秒'
  },
  {
    title: '操作',
    dataIndex: 'action',
    scopedSlots: { customRender: 'action' },
    width: 150,
    fixed: 'right'
  }
]

const accessLogColumns = [
  {
    title: '日志编号',
    dataIndex: 'infoId',
    scopedSlots: { customRender: 'infoId' }
  },
  {
    title: '用户ID',
    dataIndex: 'userId',
    scopedSlots: { customRender: 'userId' }
  },
  {
    title: '用户名',
    dataIndex: 'userName',
    scopedSlots: { customRender: 'userName' }
  },
  {
    title: 'ip地址',
    dataIndex: 'ipaddr',
    scopedSlots: { customRender: 'ipaddr' }
  },
  {
    title: '浏览器信息',
    dataIndex: 'browser',
    scopedSlots: { customRender: 'browser' }
  },
  {
    title: '操作系统',
    dataIndex: 'os',
    scopedSlots: { customRender: 'os' }
  },
  {
    title: '操作状态',
    dataIndex: 'status',
    scopedSlots: { customRender: 'status' }
  },
  {
    title: '操作信息',
    dataIndex: 'msg',
    scopedSlots: { customRender: 'msg' }
  },
  {
    title: '登录时间',
    dataIndex: 'loginTime',
    scopedSlots: { customRender: 'loginTime' }
  }
]

export default {
  name: 'Log',
  components: {
    JsonViewer
  },
  data() {
    return {
      columns,
      accessLogColumns,
      // 表格索引
      tableIndex: 1,
      tableData: [],
      operTypeList: [],
      // 访问日志
      accessLogList: [],
      loading: true,
      visible: false,
      advanced: false,
      modalForm: {},
      // 查询参数
      queryParam: {},
      queryParam2: {},
      // 分页参数
      pagination: {
        size: 'large',
        current: 1,
        pageSize: 10,
        total: 0,
        pageSizeOptions: ['10', '15', '20'],//可选的页面显示条数
        showTotal: (total, range) => {
          return ' 共' + total + '条'
        }, //展示每页第几条至第几条和总数
        hideOnSinglePage: false, // 只有一页时是否隐藏分页器
        showQuickJumper: true, //是否可以快速跳转至某页
        showSizeChanger: true //是否可以改变pageSize
      }
    }
  },
  created() {
    this.getLogList()
    getOperTypeList().then(response => {
      this.operTypeList = response.data
    })
  },
  methods: {
    changeTableIndex(key) {
      this.tableIndex = key
      if (key === 1) {
        this.getOperLogList()
      } else {
        this.getAccessLogList()
      }
    },
    // 操作日志
    getOperLogList() {
      getLogList(this.queryParam).then(response => {
        this.tableData = response.rows
        this.pagination.total = response.total
        this.loading = false
      })
    },
    // 访问日志
    getAccessLogList() {
      getAccessLogList(this.queryParam2).then(response => {
        this.accessLogList = response.rows
        this.pagination.total = response.total
        this.loading = false
      })
    },
    getLogList() {
      this.loading = true
      if (this.tableIndex === 1) {
        this.getOperLogList()
      } else {
        this.getAccessLogList()
      }
    },
    reloadData() {
      this.loading = true
      if (this.tableIndex === 1) {
        this.queryParam = {}
        this.getOperLogList()
      } else {
        this.queryParam2 = {}
        this.getAccessLogList()
      }
    },
    // 展示对话框
    showLogInfoModal(data) {
      this.visible = true
      this.modalForm = data
    },
    handleOk() {
      this.visible = false
    },
    //表格改变时触发
    handleTableChange(pagination, filters, sorter) {
      this.pagination = pagination
      // 添加分页参数
      this.queryParam.pageNum = pagination.current
      this.queryParam.pageSize = pagination.pageSize
      
      this.getLogList()
    },
    // 展开高级搜索功能
    toggleAdvanced() {
      this.advanced = !this.advanced
    },
    addDataQueryParam(date, dataList) {
      this.queryParam.startTime = dataList[0]
      this.queryParam.endTime = dataList[1]
    },
    toJson(str) {
      if (this.isJSON(str)) {
        return JSON.parse(str)
      }
      return str
    },
    isJSON(str) {
      if (typeof str == 'string') {
        try {
          let obj = JSON.parse(str)
          return !!(typeof obj == 'object' && obj)
        } catch (e) {
          return false
        }
      }
    },
    exportLogList() {
      exportLogList().then((res) => {
        let blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' })
        FileSaver.saveAs(blob, '至' + formattedDate(new Date(Date.now())) + '操作日志' + '.xlsx')
        this.$message.success('导出成功')
      })
    },
    exportAccessLogList() {
      exportAccessLogList().then((res) => {
        let blob = new Blob([res.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8' })
        FileSaver.saveAs(blob, '至' + formattedDate(new Date(Date.now())) + '访问日志' + '.xlsx')
        this.$message.success('导出成功')
      })
    }
  }
}
</script>

<style scoped>

</style>